<template>
  <a-space class="flex" v-if="tagType=='linkage_select'">
    <j-search-select-tag
      class="select-tag"
      v-model="queryParam.prov"
      :placeholder="placeholder"
      :dictOptions="districtData1"
      @change="changeArea($event, 1)"
    />
    <j-search-select-tag
      class="select-tag"
      v-model="queryParam.city"
      :placeholder="placeholder"
      :dictOptions="districtData2"
      @change="changeArea($event, 2)"
      v-if="reloading"
    />
    <j-search-select-tag
      class="select-tag"
      v-model="queryParam.district"
      :placeholder="placeholder"
      :dictOptions="districtData3"
      @change="changeArea($event, 3)"
      v-if="reloading"
    />
  </a-space>
  <a-select v-else-if="tagType=='multi_select'"
    allowClear
    mode="multiple"
    :placeholder="placeholder"
    style="width: 400px"
    :value="getValue"
    :filterOption="filterOption"
    @popupScroll="handlePopupScroll"
    @search="handleSearch"
    @change="handleInput"
    @blur="handleBlur"
  >
    <a-select-option v-for="frontSelect in frontDataZ.filter(item=>item.homeName)" :key="frontSelect.homeCode">
    <!-- //过滤一下数据是否为空 -->
      {{ frontSelect.homeName }}
    </a-select-option>
  </a-select>
</template>

<script>
import { getXzqhList, getAllHomeCodeList } from '@/api/api'
export default {
  props: {
    type: String, // linkage_select、multi_select【为空则是linkage_select】
    placeholder:{
      type: String,
      default: '请选择'
    },
    value:{
      type: Array,
      default() {
       return []
      }
    }
  },
  data() {
    return {
      tagType: null,
      reloading: true,
      districtData1: [],
      districtData2: [],
      districtData3: [],
      dictOptions: [],
      queryParam: {
        prov: null,
        city: null,
        district: null
      },
      filterOption: true,
      dataZ: [],//总数据（不会改变）
      allDataZ: [],
      frontDataZ: [], //存放前100的数据
      valueData: '',
      treePageSize: 50,
      scrollPage: 1
    }
  },
  created() {
    if (!this.type) {
      this.tagType = "linkage_select"
      this.onChangeCityData('0', 'districtData1')
    } else {
      this.tagType = this.type
      this.initAllCode()
    }
  },
  computed: {
    getValue() {
      return this.value ? this.value : [];
    },
    xzqhCode() {
      let codes = []
      for (const key in this.queryParam) {
        let index = (key==='prov') ? 0: (key==='city')? 1: (key==='district')? 2: null
        this.$set(codes, index, this.queryParam[key])
      }
      return codes
    }
  },
  watch:{
    'getValue': {
      immediate: true,
      handler(val) {
        console.log(val)
        if(this.tagType ==='linkage_select') {
          for (const key in val) {
            let type = Number(key)+1
            if(type==1 && val[key]) {
              this.$set(this.queryParam, 'prov', val[key])
            }
            if(type==2 && val[key]) {
              this.$set(this.queryParam, 'city', val[key])
            }
            if(type==3 && val[key]) {
              this.$set(this.queryParam, 'district', val[key])
            }
          }
        }
      }
    },
    // 省级
    'queryParam.prov'(newVal, oldVal){
      if(newVal) this.onChangeCityData(newVal, 'districtData2')
    },
    // 市级
    'queryParam.city'(newVal, oldVal){
      if(newVal) this.onChangeCityData(newVal, 'districtData3')
    }
  },
  methods: {
    // 获取指定归属地【type=linkage_select】
    onChangeCityData(key, field) {
      let params = {
        areaCode: key,
        flagRecursive: false,
        containsSelf: false  //true，获取areaCode的tree结构；false，获取areaCode的下级数组
      }
      getXzqhList(params).then(res => {
        if (res.success) {
          let data = res.result ? res.result : []
          this[field] = data.length>0 ? data.map(item=>{
            return {
              value: item.code.toString(),
              text: item.name
            }
          }): []
        }
      })
    },
    // 行政区划取值【type=linkage_select】
    changeArea(value, type){
      if(type==1) {
        this.$set(this.queryParam, 'city', null)
        this.$set(this.queryParam, 'district', null)
        this.districtData3 = []
      }
      if(type==2) {
        this.$set(this.queryParam, 'district', null)
      }
      this.reload()
      let datas = JSON.parse(JSON.stringify(this.xzqhCode))
      this.$emit('change', datas)
    },
    //通过接口获取手机号归属地数据【type=multi_select】
    initAllCode () {
      getAllHomeCodeList().then(res => {
        if (res && res.success) {
          // 数组对象排序
          let result = this.arrSort(res.result, 'homeCode')
          this.dataZ = result
          if(this.getValue && this.getValue.length>0) {
            let valArr = this.filterData(this.dataZ, this.getValue)
            let filterValArr = this.dataZ.filter(item=>{
                return !this.getValue.includes(item.homeCode)
            })
            let dataZ = [...valArr, ...filterValArr]
            this.dataZ = dataZ
            // this.dataZ = this.arrSort(this.dataZ, 'homeCode', this.getValue)
            this.frontDataZ = dataZ.slice(0, 50)
          } else {
            this.frontDataZ = result.slice(0, 50)
          }
        }
      }).catch(e => {
        this.$message.error('查询失败：' + e)
      })
    },
    // 下拉框搜索【type=multi_select】
    handleSearch (val) {
      this.valueData = val
      if (!val) {
        this.filterOption = true
        this.initAllCode()
      } else {
        this.frontDataZ = []
        this.scrollPage = 1
        this.filterOption = true
        this.dataZ.forEach(item => {
          if (item.homeName.indexOf(val)>= 0) {
            this.filterOption = false
            this.frontDataZ.push(item)
          }
        })
        this.allDataZ = this.frontDataZ
        this.frontDataZ = this.frontDataZ.slice(0, 50)
      }
    },
    // 下拉框下滑事件【type=multi_select】
    handlePopupScroll (e) {
      const { target } = e
      const scrollHeight = target.scrollHeight - target.scrollTop
      const clientHeight = target.clientHeight
      // 下拉框不下拉的时候
      if (scrollHeight === 0 && clientHeight === 0) {
        this.scrollPage = 1
        console.log(this.scrollPage)
      } else {
        // 当下拉框滚动条到达底部的时候
        if (scrollHeight < clientHeight + 5) {
          this.scrollPage = this.scrollPage + 1
          const scrollPage = this.scrollPage// 获取当前页
          const treePageSize = this.treePageSize * (scrollPage || 1)// 新增数据量
          const newData = [] // 存储新增数据
          let max = '' // max 为能展示的数据的最大条数
          if (this.dataZ.length > treePageSize) {
            // 如果总数据的条数大于需要展示的数据
            max = treePageSize
          } else {
            // 否则
            max = this.dataZ.length
          }
          // 判断是否有搜索
          if (this.valueData) {
            this.allDataZ.forEach((item, index) => {
              if (index < max) { // 当data数组的下标小于max时
                newData.push(item)
              }
            })
          } else {
            this.dataZ.forEach((item, index) => {
              if (index < max) { // 当data数组的下标小于max时
                newData.push(item)
              }
            })
          }

          this.frontDataZ = newData // 将新增的数据赋值到要显示的数组中
        }
      }
    },
    // 选择取值【type=multi_select】
    handleInput(e='') {
      let val;
      if (Object.keys(e).includes('target')) {
        val = e.target.value
      } else {
        val = e
      }
      this.$emit('change', val);
    },
    // 失去焦点【type=multi_select】
    handleBlur(e) {
      this.valueData = ''
      this.initAllCode()
    },
    // datas需筛选的数组集，checkedData选中的数组值
    filterData(datas, checkedData) {
      return datas.filter(item => checkedData.indexOf(item.homeCode) > -1)
    },
    /**
     * 自定义函数名：arrSort
     * @param arr： 被操作数
     * @param key： 需要用作排序的key名
     * @param valArr 拿来做排序的数据集
     */
    arrSort(arr, key, valArr) {
      arr.sort(function(a, b) {
        if(valArr) {
          return valArr.indexOf(a[key]) - valArr.indexOf(b[key])
          // qq.sort((a, b) => a.group !== b.group
          //       ? a.group - b.group
          //       : a.sp === 1 ? -1 : 1
          //   ).forEach(x => x.main = x.sp === 1 ? false : x.main)
        } else {
          return a[key] - b[key]
        }
      })
      return arr
    },
    /** 重新加载组件 */
    reload() {
      this.reloading = false
      this.$nextTick(() => (this.reloading = true))
    }
  },
  model:{
    prop: 'value',
    event: 'change'
  }
}
</script>
<style lang="less" scoped>
.flex {
  display:flex;
  > * {
    flex: 1;
  }
}
</style>
